#include "../core/nodes/classtype.h"
#include "method.h"
#include "field.h"
#include "operator.h"
#include <map>

class FeatureGroup;
class FeatureDeclaration;
class SemanticVisitorData;

struct Method;
class Field;

class FeatureDeclarationVisitor
{
 private:
	     std::map<std::string,Field>        m_fields;
		 std::map<std::string,Method>       m_methods;
	     std::vector<Operator>              m_operators;


		 FeatureGroup *       m_featgroup;  //!< Feature group
		 FeatureDeclaration * m_featdecl; //!< Feature declaration
		 FeatureSpecName    * m_featsn;   //!< Feature spec name

		 std::string m_class;
		 std::vector<std::string> m_clients; //!< Clients data

		 SemanticVisitorData * m_data;  //!< Data for semantic visitor
		 
		 std::vector<std::string> getSignature(const Method & m);

		 bool containsSignature(const std::string & op,const std::vector<std::string> & sig);
		 bool isValidOperator(Operator & op);
 public:
	     inline FeatureDeclaration * currentDeclaration() { return m_featdecl; } //!< Current declaration
	     inline FeatureGroup * currentGroup() {return m_featgroup; } //!< Current group
		 inline FeatureSpecName * currentSpec() {return m_featsn; }  //!< Current spec
		 inline const std::string & className() {return m_class; }
		 inline std::vector<std::string> & clients() { return m_clients; }
		 inline SemanticVisitorData * data() { return m_data;}
		 /*! Default visitor
		  */
	     inline FeatureDeclarationVisitor() {}
		 /*! Sets current scanned node
		  */ 
		 inline void setClass(const std::string & classname) { m_class=classname;}
		 /*! Sets a feature group
		  */
		 inline void setFeatureGroup(FeatureGroup * fg)  { m_featgroup=fg; }
		 /*! Sets a feature declaration
		  */
		 inline void setFeatureDecl(FeatureDeclaration * fd) { m_featdecl=fd; }
		 /*! Feature specification name
			 \param[in] fs fs name
		  */
		 inline void setSpecName(FeatureSpecName * fs)   { m_featsn=fs;}
		 /*! Sets a semantic visitor
		  */
		 inline void setData(SemanticVisitorData * data) {m_data=data; }
		 /*! Sets a feature group
		  */
		 inline void setClients(const std::vector<std::string> & c) {m_clients=c;}
		 
		 void addField(const std::string & s, const Field & f);
		 void addMethod(const std::string & s, const Method & m);
		 void addOperator(const std::string & methname, const Method & m, const std::string & opname );

		 const std::map<std::string,Field>     &  fields() const {return m_fields;}
		 const std::map<std::string,Method>    &  methods() const {return m_methods;}
		 const std::vector<Operator>  &  operators() const { return m_operators; }
};